Analog Outputs via I/O Adapters Basic

Motivation

Sometimes it is desirable to set an analog output pin to a specific voltage to test e.g. the reaction of the device-under-test. In this tutorial we will periodically change the value of an analog output and measure its value using a logic analyzer.

Pre-requisites

  • You have a working miniHIL project setup which you either created using the template project or the example project.

  • You have basic eTrice knowledge. E.g. you successfully finished the eTrice PingPong Tutorials.

  • To be able to see the output voltage you will need to measure the analog output pint 0. The picture below shows the connection using a SALEAE™ logic analyzer.

AnalogOutputWiring
  • Optionally, to be able to see some output, make sure you can log as described in here. Note that in this case you only need the USB connection. Log messages will be generated by the analog output actor.

Tip The contents of this How-To is also part of the miniHIL Examples project. Look there for a fully functional sample in model-user/examples/analogio.room.

Accessing analog outputs using adapters

Analog outputs can be accessed using two different mechanisms. One way is to directly use the analog output service provision points (SPP). This is however not recommended for beginners.
The other option, which is described in this HowTo, is to use the provided analog output adapters.

Creating The Output Actor

To set the output voltage we will create an actor driven by a timer and state machine to do the periodic updates.

We will place the actor in MiniHilProject/model-user/MiniHILApplication.room. Add the lines shown below.

	import etrice.api.types.*
	import etrice.api.timer.PTimer
	import etrice.api.logger.PLogger
	import minihil.api.analog.PAnOut
	import minihil.api.adapters.io.*

	/*
	 * ADigitalOutWriter demonstrates writing to a digital output
	 */
	ActorClass AAnalogOutWriter {
		Structure {
			ActorRef outputAdapter: AAnOutAdapter00to03 1
			conjugated Port outPort: PAnOut 2
			Binding outPort and outputAdapter.anOut00 3
			SAP timer: PTimer 4
			SAP logger: PLogger 5
			Attribute outputValue: uint32 6
			Attribute outputDelta: int32 7
		}
		Behavior {
    	}
}
1 We use the adapter that allows us to access analog outs 0-3
2 This port is needed to connect the adapter to the state machine we will create in the next step
3 Connecting the actor-internal port to the adapter
4 The timer service is used to receiver periodic timer ticks
5 The logging service is used for some output to see whether the actor is alive and kicking
6 This is the actual value to be written to the output
7 This is the delta by which the output will change on every tick

Note that so far the actor is not doing anything. For this we will create a small state machine in the next step.

Creating the state machine

Put your cursor on AAnalogOutWriter and press ALT-B to open the behavioral editor of eTrice. This is empty right now. Add an initial state and a state called Waiting. Then create a transition from the initial state to Waiting. Add the action code to initialize the attributes and start the timer as shown below:

AnalogOutputInitTransition

Add another transition from Waiting to itself. In this transition we will compute the next value to set and send it to the analog output adapter. The picture below shows the configuration of the transition.

AnalogOutputSendTransition

Note that the values for the analog output are given in mV. So with the code shown above the output should oscillate between 0V and 1V.

The complete state machine should look like this:

AnalogOutputFSM

With this your actor should look as follows:

	ActorClass AAnalogOutWriter {
		Structure {
			ActorRef outputAdapter: AAnOutAdapter00to03
			conjugated Port outPort: PAnOut
			Binding outPort and outputAdapter.anOut00
			SAP timer: PTimer
			SAP logger: PLogger
			Attribute outputValue: uint32
			Attribute outputDelta: int32
		}
		Behavior {
			StateMachine {
				State Waiting {
				}
				Transition init: initial -> Waiting {
					action '''
						outputValue = 0;
						outputDelta = 100;
						timer.startTimer(100);
					'''
				}
				Transition sendTransition: Waiting -> Waiting {
					triggers {
						<timeout: timer>
					}
					action '''
						if (outputValue == 1000)
						{
						    outputDelta = -100;
						}
						if (outputValue == 0)
						{
						    outputDelta = 100;
						}

						outputValue += outputDelta;
						logger.logF("Setting value to %d", outputValue);
						outPort.setValue(outputValue);
					'''
				}
			}
		}
	}

Instantiating the actor

Before we can run the example we need to instantiate the actor inside the Application actor. Note that the actor has no external interface, so no binding to ports or other actors is necessary. Also, it is started through the init transition, so no extra action is necessary for it to run.

RoomModel MiniHilProject {
    ...
	ActorClass Application {
		Structure {
            ...
			ActorRef analogOutputExample : AAnalogOutWriter
			...
		}
	}
}

Running the example

Now build and run your code. When you start it you should see output similar to the following (captured with SALEAE™):

SALEAE

If you are capturing the log messages you will see the following:

Logging output with HTERM

To be able to use the provided adapters you have to import the adapter io api namespace:

Summary

  • Analog output adapters can be used to set the voltage of analog outputs.

  • Analog output adapters are specified in the minihil.adapters.api.io namespace.

  • Analog out adapters are named AAnOutAdapterXXtoYY (AnalogOut pins 0-15).

See Also